package ca.cbc.gisdigester.digester;

import ca.cbc.feed.tweet.Status;
import ca.cbc.feed.tweet.Statuses;
import ca.cbc.feed.tweet.User;
import ca.cbc.giscommon.entity.Source;
import ca.cbc.giscommon.entity.Tweet;
import ca.cbc.giscommon.entity.TwitterUser;
import ca.cbc.giscommon.util.GISConfig;
import ca.cbc.giscommon.util.GeometryUtil;
import ca.cbc.giscommon.util.StringUtil;
import ca.cbc.gisdigester.Main;
import ca.cbc.gisdigester.util.XmlHelper;
import com.vividsolutions.jts.geom.Geometry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.xml.bind.JAXBException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLConnection;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Locale;

public enum TweetDigester {
    instance;
    private Logger logger = LoggerFactory.getLogger(TweetDigester.class);
   
     
    /**
     * @param source -- the source object
     */
    public HashMap<String, Tweet> digest(Source source, HashMap<String, TwitterUser> users) {
        logger.info("**Digesting Twitter Feed URL {}.", source.getLink());
        String sourceLink = source.getLink();
        HashMap<String, Tweet> tweets = new HashMap<String, Tweet>();
        try {
            if (sourceLink.startsWith("http")) {    //input is a url
            	
            	URLConnection connection = new URL(sourceLink).openConnection();
            	GISConfig.instance.changeConnectionTimeouts(connection);

                Statuses statuses = XmlHelper.instance.<Statuses>digestXmlFile("ca.cbc.feed.tweet",connection.getInputStream() );
              

                Calendar twoDayAgo = Calendar.getInstance(Locale.CANADA);
                twoDayAgo.add(Calendar.DATE, -2);

                for (Status status : statuses.getStatus()) {
                    String createdAtString = status.getCreatedAt();
                    long createdAt = new SimpleDateFormat("EEE MMM d HH:mm:ss Z yyyy").parse(createdAtString).getTime();
                    Calendar createdAtCalendar = Calendar.getInstance();
                    createdAtCalendar.setTimeInMillis(createdAt);

                    if (twoDayAgo.before(createdAtCalendar)) {
                        String statusId = status.getId();

                        //Only go ahead with the insertion if there is GIS information associated with it
                        if (!tweets.containsKey(statusId) && status.getCoordinates() != null) {
                            Geometry theGeom = null;
                            String coordString = status.getCoordinates().getPoint();
                            int indexOfSpace = coordString.indexOf(" ");

                            if (indexOfSpace == -1)
                                logger.error("Coordinates do not represent a point");

                            theGeom = GeometryUtil.instance.parsePoint(coordString.substring(indexOfSpace) + ", " + coordString.substring(0, indexOfSpace));

                            User user = status.getUser();
                            String screenName = user.getScreenName().trim().toLowerCase();

                            TwitterUser twitterUser;
                            if (users.containsKey(screenName)) {
                                twitterUser = users.get(screenName);
                                twitterUser.setUserName(StringUtil.instance.trimIfNotNull(user.getName()));
                                twitterUser.setAvatarURL(StringUtil.instance.trimIfNotNull(user.getProfileImageUrl()));
                            } else {
                                twitterUser = new TwitterUser(StringUtil.instance.trimIfNotNull(screenName),
                                        StringUtil.instance.trimIfNotNull(user.getName()), StringUtil.instance.trimIfNotNull(user.getProfileImageUrl()));
                                users.put(screenName, twitterUser);
                            }
                            Tweet tweet = new Tweet(StringUtil.instance.trimIfNotNull(status.getText()),
                                    StringUtil.instance.trimIfNotNull(statusId), createdAt, theGeom, source, twitterUser);
                            logger.debug(tweet.toString());
                            tweets.put(statusId, tweet);
                        }
                    }
                }
            }
        } catch (JAXBException e) {
            logger.error("JAXBException.", e);
        } catch (IllegalArgumentException e) {
            logger.error("Error when parsing url/file {}.", sourceLink, e);
        } catch (MalformedURLException e) {
            logger.error("Error when parsing url/file {}.", sourceLink, e);
        } catch (ParseException e) {
            logger.error("Created At data could not be parsed properly in {}.", sourceLink, e);
        } catch (IOException e) {
            logger.error("Error when parsing url/file {}.", sourceLink, e);
        } 

        logger.info("**{} Twitter Feeds with URL {} digested.", tweets.size(), source.getLink());
        return tweets;
    }
}
